fix(codegen): support nested patterns inside tuple patterns (WASM)#612
Merged
Conversation
The core-Wasm backend rejected any tuple sub-pattern that wasn't a plain
variable or wildcard (UnsupportedFeature "Only variable and wildcard patterns
supported in tuple patterns") — which stdlib/option.affine and result.affine
hit. gen_pattern now recurses per tuple element: each element is loaded into a
temp local and matched against its sub-pattern, with the per-element test bools
ANDed together. Every gen_pattern result is one-bool-net with net-zero binds,
so the combination is stack-safe; binds register via the threaded ctx (the same
mechanism constructor-argument patterns use).
Verified under node: `match (a,b) { (0,y)=>y, (x,0)=>x+100, (x,y)=>x+y }`
selects the right arm and binds correctly — (0,5)->5, (7,0)->107, (3,4)->7.
option.affine / result.affine now get PAST this gap (they next hit a separate
`panic`-builtin gap in the Wasm backend, tracked in #607). dune test 461 green;
adds a Wasm nested-tuple regression test.
Part of #607.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lz7pRcec2Z3tVtaAhvB3M8
🔍 Hypatia Security ScanFindings: 43 issues detected
View findings[
{
"reason": "Action denoland/setup-deno@v2 needs attention",
"type": "unpinned_action",
"file": "publish-jsr.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Issue in scorecard-enforcer.yml",
"type": "scorecard_publish_with_run_step",
"file": "scorecard-enforcer.yml",
"action": "split_scorecard_publish_job",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in instant-sync.yml",
"type": "secret_action_without_presence_gate",
"file": "instant-sync.yml",
"action": "peter-evans/repository-dispatch",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Shell execution -- validate input before passing to shell (1 occurrences, CWE-78)",
"type": "js_exec_sync",
"file": "/home/runner/work/affinescript/affinescript/packages/affinescript-cli/mod.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "Shell execution -- validate input before passing to shell (2 occurrences, CWE-78)",
"type": "js_exec_sync",
"file": "/home/runner/work/affinescript/affinescript/packages/affine-vscode/mod.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "Shell execution -- validate input before passing to shell (1 occurrences, CWE-78)",
"type": "js_exec_sync",
"file": "/home/runner/work/affinescript/affinescript/affinescript-vite/src/affine-plugin-improved.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
},
{
"reason": "expect() in hot path (32 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/affinescript/affinescript/affinescriptiser/src/codegen/wasm_gen.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "expect() in hot path (29 occurrences, CWE-754)",
"type": "expect_in_hot_path",
"file": "/home/runner/work/affinescript/affinescript/affinescriptiser/src/codegen/affine_gen.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unsafe block -- requires SAFETY comment (2 occurrences, CWE-676)",
"type": "unsafe_block",
"file": "/home/runner/work/affinescript/affinescript/runtime/src/panic.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
},
{
"reason": "unsafe block -- requires SAFETY comment (1 occurrences, CWE-676)",
"type": "unsafe_block",
"file": "/home/runner/work/affinescript/affinescript/runtime/src/alloc.rs",
"action": "flag",
"rule_module": "code_safety",
"severity": "medium"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
hyperpolymath
added a commit
that referenced
this pull request
Jun 21, 2026
## What Merges current `main` into `feat/solo-core-metatheory-proofs` and resolves all conflicts, so that **#614 stops being `mergeable_state: dirty`**. While #614 is dirty, GitHub cannot build the merge commit, so its entire CI suite is suppressed (only `lint-workflows` runs). Merging this PR into the feature branch un-blocks #614's CI. ## Why it was needed #614 branched off an old `main` (merge-base 61 commits back) and conflicts with the standalone-CI + codegen work that has since landed (#602, #603, #604, #606, #609, #610, #611, #612, #613). ## Conflict resolutions (5 files) | File(s) | Resolution | |---|---| | `governance.yml`, `scorecard.yml`, `scorecard-enforcer.yml`, `hypatia-scan.yml` | Take `main`'s **standalone** versions. The branch re-adopted the estate `standards` reusables that `main` deliberately dropped (#603/#604) to stop run-creation `startup_failure`s. `main`'s `hypatia-scan.yml` also restores the permissions Hypatia needs (`security-events: write`, `pull-requests: write`, `secrets: inherit`) and the `MPL-2.0` SPDX id the Palimpsest license doc mandates for tooling. | | `docs/PROOF-NEEDS.md` | Drop the branch's stale 103-line `.md`; keep `main`'s canonical 359-line `.adoc` (#609). Also satisfies DOC-FORMAT. | | `docs/history/MODULE-SYSTEM-PROGRESS` | Keep the branch's `.md`→`.adoc` migration; **port** `main`'s additive #138 codegen-follow-up note + status-table row into the `.adoc` so `main`'s work is preserved. | `spark-theatre-gate.yml` and `mirror.yml` were identical to `main`. ## Verification (merged tree) - `dune build` — clean - `dune test` — **534/534 pass** (incl. `cross-module constructor linking, Wasm (#138)`, `Wasm nested tuple patterns`, `Deno-ESM / JS no duplicate Option/Result constructor`) - wasm-runtime harness (`tools/run_codegen_wasm_tests.sh`) — all pass - workflow scan — no `startup_failure` risk introduced ## How to use Merge this into `feat/solo-core-metatheory-proofs`. #614 then becomes mergeable and its full CI runs. > Routed via this branch because the environment only permits pushes to `claude/inspiring-newton-dg5wov`, not directly to the feature branch. Un-blocks #614. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Lz7pRcec2Z3tVtaAhvB3M8 --- _Generated by [Claude Code](https://claude.ai/code/session_01Lz7pRcec2Z3tVtaAhvB3M8)_ --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: hyperpolymath <paraordinate@yahoo.co.uk>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Item 3a of the batch — the WASM tuple-pattern half of #607.
Bug
The core-Wasm pattern compiler rejected any tuple sub-pattern that wasn't a bare variable/wildcard:
That's the gap
stdlib/option.affineandresult.affinehit (after #138/#604 got them past the constructor-linking gap).Fix
gen_pattern'sPatTuplecase now recurses per element: load elementiinto a temp local, match it against sub-patterni, andI32Andthe per-element test bools. This is stack-safe because everygen_patternresult is one-bool-net with net-zero binds (see PatVar/PatLit/PatCon); binds register through the threaded ctx, exactly like constructor-argument patterns. Literals, constructors, and nested tuples now work as tuple sub-patterns.Verified (under node)
option.affine/result.affinenow compile past the tuple-pattern gap (they next hit a separatepanic-builtin gap in the Wasm backend — tracked in Codegen follow-ups surfaced by the #138 / standalone-CI work #607, not this PR).dune test461 green; adds a Wasm nested-tuple regression test.Addresses the tuple-pattern item in #607 (the
panicbuiltin and the mixed-representationmatchremain).🤖 Generated with Claude Code
https://claude.ai/code/session_01Lz7pRcec2Z3tVtaAhvB3M8
Generated by Claude Code